
mixin importStandardModulesFor!("writeln", "sin");

void main()
{
    writeln("sin(1) = ", sin(1));
}


//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

/*
Automatically imports standard modules needed to use given identifiers.
 */
template importStandardModulesFor(ids...)
{
    static if (ids.length > 0)
    {
        mixin importModules!(searchIdentifier!(ids[0], STD_MODULES));
        mixin importStandardModulesFor!(ids[1 .. $]);
    }
}

private alias TypeTuple!("std.algorithm", "std.array", "std.atomics",
    "std.base64", "std.bigint", "std.bitmanip", "std.boxer", "std.complex",
    "std.compiler", "std.contracts", "std.conv", "std.cpuid", "std.cstream",
    "std.ctype", "std.date", "std.datebase", "std.dateparse", "std.demangle",
    "std.encoding", "std.file", "std.format", "std.functional", "std.getopt",
    "std.intrinsic", "std.iterator", "std.json", "std.loader", "std.math",
    "std.md5", "std.metastrings", "std.mmfile", "std.numeric", "std.outbuffer",
    "std.path", "std.perf", "std.process", "std.random", "std.range",
    "std.regex", "std.regexp", "std.signals", "std.socket", "std.socketstream",
    "std.stdint", "std.stdio", "std.stdiobase", "std.stream", "std.string",
    "std.syserror", "std.system", "std.traits", "std.typecons", "std.typetuple",
    "std.uni", "std.uri", "std.utf", "std.variant", "std.xml", "std.zip",
    "std.zlib") STD_MODULES;


//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

import std.typetuple;

/*
Searches for the identifier $(D ident) in given modules.
 */
template searchIdentifier(string ident, modules...)
{
    alias searchIdentifierImpl!(ident, modules).hits searchIdentifier;
}

private template searchIdentifierImpl(string ident, modules...)
{
    static if (modules.length > 0)
    {
        mixin("static import " ~ modules[0] ~ ";");
        alias searchIdentifierImpl!(ident, modules[1 .. $]).hits nextHits;
        static if ( __traits(hasMember, mixin(modules[0]), ident) )
            alias TypeTuple!(modules[0], nextHits) hits;
        else
            alias                        nextHits  hits;
    }
    else
    {
        alias TypeTuple!() hits;
    }
}


/*
mixin to import modules.
 */
template importModules(mods...)
{
    static if (mods.length > 0)
    {
        mixin("import " ~ mods[0] ~";");
        mixin importModules!(mods[1 .. $]);
    }
}


